package com.wandian.texas.demo;

import java.util.concurrent.Executors;
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.ThreadFactory;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.locks.ReentrantLock;

import com.wandian.util.Log;

/**
 * java中断所，普通情况下，如果两个线程竞争一个锁，当前者被中断，后者依然在苦苦等锁 ReentrantLock
 * 
 * @author long
 * @Create 2012-10-9 下午2:10:56
 * @QQ 108232706
 * @version 1.0
 * @description ReentrantLockTest
 */
public class ReentrantLockTest {

	public class BufferInterruptibly {

		private final ReentrantLock lock = new ReentrantLock();

		public void write() {
			lock.lock();
			try {
				long startTime = System.currentTimeMillis();
				System.out.println("开始往这个buff写入数据…");
				for (;;)// 模拟要处理很长时间
				{
					if (System.currentTimeMillis()
							- startTime > Integer.MAX_VALUE)
						break;
				}
				System.out.println("终于写完了");
			} finally {
				lock.unlock();
			}
		}

		public void read() throws InterruptedException {
			lock.lockInterruptibly();// 注意这里，可以响应中断
			try {
				System.out.println("从这个buff读数据");
			} finally {
				lock.unlock();
			}
		}

	}

	public class Reader implements Runnable {

		private final BufferInterruptibly buff;

		public Reader(BufferInterruptibly buff) {
			this.buff = buff;
		}

		public void run() {

			try {
				buff.read();// 可以收到中断的异常，从而有效退出
			} catch (InterruptedException e) {
				System.out.println("我不读了");
			}

			System.out.println("读结束");
			System.gc();

		}

	}

	/**
	 * Writer倒不用怎么改动
	 */
	public class Writer implements Runnable {

		private final BufferInterruptibly buff;

		public Writer(BufferInterruptibly buff) {
			this.buff = buff;
		}

		public void run() {
			buff.write();
		}

	}

	class MyThreadFactory implements ThreadFactory, Thread.UncaughtExceptionHandler {
		private final boolean daemon;
		private final String threadName;

		public MyThreadFactory(String threadName, boolean daemon)
		{
			this.threadName = threadName;
			this.daemon = daemon;
		}

		public Thread newThread(Runnable r) {
			Thread t = new Thread(r, this.threadName);
			t.setDaemon(this.daemon);
			t.setUncaughtExceptionHandler(this);
			return t;
		}

		public void uncaughtException(Thread thread, Throwable throwable) {
			Log.error("Uncaught Exception in thread " + thread.getName(), throwable);
		}
	}

	public void Test() {
		BufferInterruptibly buff = new BufferInterruptibly();

		final Writer writer = new Writer(buff);
		final Reader reader = new Reader(buff);
		ScheduledExecutorService service = Executors.newScheduledThreadPool(3, new MyThreadFactory("testMyThreadFactory", false));// 创建3个线程的池
		for (int i = 0; i < 10; i++) {
			System.out.println("创建线程" + i);
			Runnable run = new Runnable() {
				public void run() {
					System.out.println("启动线程");
				}
			};
			// 在未来某个时间执行给定的命令,超出corePoolSize的command在队列里等待
			service.execute(run);
		}
		// Future<?> f1= service.submit(writer);
		// service.submit(reader);
		// 程序运行5s后,所有任务停止
		// try {
		// Thread.sleep(5000);
		//
		// } catch (InterruptedException ex) {
		//
		// }
		// 关闭启动线程，不接受新来的command
		service.shutdown();
		
		// 等待子线程结束,这里阻塞，再继续执行下面的代码
		try {
			service.awaitTermination(Long.MAX_VALUE, TimeUnit.DAYS);
		} catch (InterruptedException e) {
			e.printStackTrace();
		}
		System.out.println("all thread complete");
		// service.shutdownNow();

	}
}
